﻿Imports System.Text

''' <summary>
''' IN条件
''' </summary>
''' <remarks>
''' 1つの列に対し、複数の条件を指定できます。
''' </remarks>
Public Class InCondition
    Implements ICondition

    Private Sub New()
    End Sub

    Public Shared Function Create(literalName As String, values As IEnumerable)
        If literalName Is Nothing OrElse String.IsNullOrEmpty(literalName) Then Throw New ArgumentNullException("literalName")
        If values Is Nothing Then Throw New ArgumentNullException("values")

        Dim c As New InCondition
        c.LiteralName = literalName
        For Each item In values
            c.Values.Add(item)
        Next

        Return c
    End Function

    Private _literalName As String
    ''' <summary>
    ''' リテラル名
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property LiteralName As String
        Get
            Return _literalName
        End Get
        Set(value As String)
            _literalName = value
        End Set
    End Property

    Private _values As New List(Of Object)
    ''' <summary>
    ''' 値
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Values As IList(Of Object)
        Get
            Return _values
        End Get
    End Property

    ''' <summary>
    ''' SQL文を組み立てます
    ''' </summary>
    ''' <param name="setParameter">パラメータ名取得デリゲート。第1引数＝パラメータ名、戻り値＝パラメータ名。</param>
    ''' <returns>SQL文</returns>
    ''' <remarks></remarks>
    Public Function BuildSql(setParameter As Func(Of Object, String)) As String Implements ICondition.BuildSql
        If setParameter Is Nothing Then Throw New ArgumentNullException("setParameter")
        If Me.Values Is Nothing OrElse Me.Values.Any = False Then Return String.Empty

        Dim s As New StringBuilder

        '列名
        Dim colName = Me.LiteralName

        For Each item In Me.Values
            'パラメータ値
            Dim val = item

            'パラメータ名
            Dim pname = setParameter.Invoke(val)

            s.AppendDelimiter(", ").Append(pname)
        Next

        'SQL文返却
        If Me.Values.Count = 1 Then
            Return "T0." & colName & " = " & s.ToString
        Else
            Return "T0." & colName & " IN (" & s.ToString & ")"
        End If
    End Function
End Class
